package ctrservice

import (
    "github.com/astaxie/beego/logs"
    "fmt"
    "encoding/json"
    "io/ioutil"
    "cloud_worm/util/uhttp"
    "cloud_worm/util/uid"
    "cloud_worm/util/proto/urpc"
    "cloud_worm/util/umodels/mysqldb"
    "cloud_worm/util/umodels/mysqldb/dbmanager"
    "cloud_worm/wormweb/controllers/ctrconfig"
    "cloud_worm/wormweb/controllers/ctrutil"
)

// @Description: 执行命令的接口
type DoCmdController struct {
    ctrconfig.LoginCtr
}

func (d *DoCmdController) Post() {
    d.Admin()

    type CmdInput struct {
        IP          string
        Cmd         string
        Timeout     int
    }
    body, err := ioutil.ReadAll(d.Ctx.Request.Body)
    if err != nil {
        logs.Error(fmt.Sprintf("read body error: %s", err.Error()))
        d.Data["json"] = uhttp.CreateErrResponse(uhttp.RespCodeReqBodyErr, err.Error(), nil)
        d.ServeJSON()
        return
    }
    var cmdInput CmdInput
    if err = json.Unmarshal(body, &cmdInput); err != nil {
        logs.Error(fmt.Sprintf("Unmarshal input error: %s", err.Error()))
        d.Data["json"] = uhttp.CreateErrResponse(uhttp.RespCodeReqBodyErr, "Unmarshal input err.", nil)
        d.ServeJSON()
        return
    }
    if cmdInput.IP == mysqldb.SelectStrAll {
        logs.Error(fmt.Sprintf("input ip error."))
        d.Data["json"] = uhttp.CreateErrResponse(uhttp.RespCodeParamErr, "input ip error.", nil)
        d.ServeJSON()
        return
    }
    if cmdInput.Cmd == mysqldb.SelectStrAll {
        logs.Error(fmt.Sprintf("input cmd error."))
        d.Data["json"] = uhttp.CreateErrResponse(uhttp.RespCodeParamErr, "input cmd error.", nil)
        d.ServeJSON()
        return
    }

    if cmdInput.Timeout < 60 {
        cmdInput.Timeout = 60
    }

    // 匹配ip对应的wolagent
    w := &dbmanager.WormId{}
    err = w.SelectValidByIP(cmdInput.IP)
    if err != nil {
        // todo: 创建异步任务fast task，执行 agent install 操作

        errMsg := fmt.Sprintf("agent for ip error: %s, %s", cmdInput.IP, err.Error())
        logs.Error(errMsg)
        d.Data["json"] = uhttp.CreateErrResponse(uhttp.RespCodeSystemErr, errMsg, nil)
        d.ServeJSON()
        return
    }
    if w.Status == dbmanager.AgentOffline {
        // todo: 创建异步任务fast task，执行 agent install 操作

        errMsg := fmt.Sprintf("wolagent no online: %s", cmdInput.IP)
        logs.Error(errMsg)
        d.Data["json"] = uhttp.CreateErrResponse(uhttp.RespCodeSystemErr, errMsg, nil)
        d.ServeJSON()
        return
    }

    // 发送请求
    args := urpc.CmdArgs{
        Id: w.AgentId,
        TaskId: uid.TaskIdProducer().CreateTaskId(),
        Cmd: cmdInput.Cmd,
        TimeOut: cmdInput.Timeout,
    }
    reply := urpc.CmdReply{}
    rpcAddr, _ := ctrutil.GetRpcIDForAccessSrv(w.ServerAddr)
    err = ctrutil.AccessSrvRpc.Call(rpcAddr, "ExecAction.ExecCmd", &args, &reply)
    if err != nil {
        errMsg := fmt.Sprintf("rpc call: %s", err.Error())
        logs.Error(errMsg)
        d.Data["json"] = uhttp.CreateErrResponse(uhttp.RespCodeSystemErr, errMsg, nil)
        d.ServeJSON()
        return
    }

    d.Data["json"]= uhttp.CreateOkResponse(reply)
    d.ServeJSON()
    return
}